
<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<title>monkeypatching: Go Coverage Report</title>
		<style>
			body {
				background: black;
				color: rgb(80, 80, 80);
			}
			body, pre, #legend span {
				font-family: Menlo, monospace;
				font-weight: bold;
			}
			#topbar {
				background: black;
				position: fixed;
				top: 0; left: 0; right: 0;
				height: 42px;
				border-bottom: 1px solid rgb(80, 80, 80);
			}
			#content {
				margin-top: 50px;
			}
			#nav, #legend {
				float: left;
				margin-left: 10px;
			}
			#legend {
				margin-top: 12px;
			}
			#nav {
				margin-top: 10px;
			}
			#legend span {
				margin: 0 5px;
			}
			.cov0 { color: rgb(192, 0, 0) }
.cov1 { color: rgb(128, 128, 128) }
.cov2 { color: rgb(116, 140, 131) }
.cov3 { color: rgb(104, 152, 134) }
.cov4 { color: rgb(92, 164, 137) }
.cov5 { color: rgb(80, 176, 140) }
.cov6 { color: rgb(68, 188, 143) }
.cov7 { color: rgb(56, 200, 146) }
.cov8 { color: rgb(44, 212, 149) }
.cov9 { color: rgb(32, 224, 152) }
.cov10 { color: rgb(20, 236, 155) }

		</style>
	</head>
	<body>
		<div id="topbar">
			<div id="nav">
				<select id="files">
				
				<option value="file0">github.com/jianghushinian/blog-go-example/test/monkeypatching/main.go (52.6%)</option>
				
				</select>
			</div>
			<div id="legend">
				<span>not tracked</span>
			
				<span class="cov0">not covered</span>
				<span class="cov8">covered</span>
			
			</div>
		</div>
		<div id="content">
		
		<pre class="file" id="file0" style="display: none">package main

import (
        "encoding/json"
        "fmt"
        "io"
        "net/http"
        "strconv"

        "github.com/julienschmidt/httprouter"
        "gorm.io/driver/mysql"
        "gorm.io/gorm"
)

type User struct {
        ID   int
        Name string
}

func NewMySQLDB(host, port, user, pass, dbname string) (*gorm.DB, error) <span class="cov0" title="0">{
        dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&amp;parseTime=True&amp;loc=Local",
                user, pass, host, port, dbname)
        return gorm.Open(mysql.Open(dsn), &amp;gorm.Config{})
}</span>

func NewUserHandler(store *gorm.DB) *UserHandler <span class="cov8" title="1">{
        return &amp;UserHandler{store: store}
}</span>

type UserHandler struct {
        store *gorm.DB
}

func (h *UserHandler) CreateUser(w http.ResponseWriter, r *http.Request, _ httprouter.Params) <span class="cov8" title="1">{
        w.Header().Set("Content-Type", "application/json")

        body, err := io.ReadAll(r.Body)
        if err != nil </span><span class="cov0" title="0">{
                w.WriteHeader(http.StatusBadRequest)
                _, _ = fmt.Fprintf(w, `{"msg":"%s"}`, err.Error())
                return
        }</span>
        <span class="cov8" title="1">defer func() </span><span class="cov8" title="1">{ _ = r.Body.Close() }</span>()

        <span class="cov8" title="1">u := User{}
        if err := json.Unmarshal(body, &amp;u); err != nil </span><span class="cov0" title="0">{
                w.WriteHeader(http.StatusBadRequest)
                _, _ = fmt.Fprintf(w, `{"msg":"%s"}`, err.Error())
                return
        }</span>

        <span class="cov8" title="1">if err := h.store.Create(&amp;u).Error; err != nil </span><span class="cov0" title="0">{
                w.WriteHeader(http.StatusInternalServerError)
                _, _ = fmt.Fprintf(w, `{"msg":"%s"}`, err.Error())
                return
        }</span>
        <span class="cov8" title="1">w.WriteHeader(http.StatusCreated)</span>
}

func (h *UserHandler) GetUser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) <span class="cov8" title="1">{
        id := ps[0].Value
        uid, _ := strconv.Atoi(id)

        w.Header().Set("Content-Type", "application/json")
        var u User
        if err := h.store.First(&amp;u, uid).Error; err != nil </span><span class="cov0" title="0">{
                w.WriteHeader(http.StatusInternalServerError)
                _, _ = fmt.Fprintf(w, `{"msg":"%s"}`, err.Error())
                return
        }</span>
        <span class="cov8" title="1">_, _ = fmt.Fprintf(w, `{"id":%d,"name":"%s"}`, u.ID, u.Name)</span>
}

func setupRouter(handler *UserHandler) *httprouter.Router <span class="cov8" title="1">{
        router := httprouter.New()
        router.POST("/users", handler.CreateUser)
        router.GET("/users/:id", handler.GetUser)
        return router
}</span>

func main() <span class="cov0" title="0">{
        mysqlDB, _ := NewMySQLDB("localhost", "3306", "user", "password", "test")
        handler := NewUserHandler(mysqlDB)
        router := setupRouter(handler)
        _ = http.ListenAndServe(":8000", router)
}</span>
</pre>
		
		</div>
	</body>
	<script>
	(function() {
		var files = document.getElementById('files');
		var visible;
		files.addEventListener('change', onChange, false);
		function select(part) {
			if (visible)
				visible.style.display = 'none';
			visible = document.getElementById(part);
			if (!visible)
				return;
			files.value = part;
			visible.style.display = 'block';
			location.hash = part;
		}
		function onChange() {
			select(files.value);
			window.scrollTo(0, 0);
		}
		if (location.hash != "") {
			select(location.hash.substr(1));
		}
		if (!visible) {
			select("file0");
		}
	})();
	</script>
</html>
